package com.planet.utils;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.net.URLCodec;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * Created by java on 15/11/13.
 */
public class UtilTools {

	    private static final Map<String,String> map = new HashMap<String,String>();
	    private static final Map<String,String>  mapurl = new HashMap<String,String>();
	    public final static long workerId = 0L;
	    private final static long twepoch = 1288834974657L;
	    private static long sequence = 0L;
	    private final static long workerIdBits = 4L;
	    public final static long maxWorkerId = -1L ^ -1L << workerIdBits;
	    private final static long sequenceBits = 10L;
	    private final static long workerIdShift = sequenceBits;
	    private final static long timestampLeftShift = sequenceBits + workerIdBits;
	    public final static long sequenceMask = -1L ^ -1L << sequenceBits;
	    private static long lastTimestamp = -1L;

	    private static Logger logger = LogManager.getLogger(UtilTools.class);

	    static  {
	        map.put("20001", "test-file");
	        map.put("20002", "test-image");
	        map.put("20003", "test-video");
//	        map.put("30001", "db-file");
//	        map.put("30002", "db-image");
//	        map.put("30003", "db-video");
//	        map.put("40001", "buy-file");
//	        map.put("40002", "buy-image");
//	        map.put("40003", "buy-video");
	        map.put("50001", "edu-file");
	        map.put("50002", "edu-image");
	        map.put("50003", "edu-video");
	        map.put("50004", "edu-voice");

	        //mapurl.put("20001", "https://dn-danbai-test-file.qbox.me");
	        mapurl.put("20001", "http://test-danbai-file.danbai.me");
	        mapurl.put("20002", "http://test-danbai-image.danbai.me");
	        mapurl.put("20003", "http://test-danbai-video.danbai.me");
//
//	        mapurl.put("30001", "http://file-db.danbai.me");
//	        mapurl.put("30002", "http://image-db.danbai.me");
//	        mapurl.put("30003", "http://video-db.danbai.me");
//
//	        mapurl.put("40001", "http://res.genshuimai.com");
//	        mapurl.put("40002", "http://image.genshuimai.com");
//	        mapurl.put("40003", "http://video.genshuimai.com");
	        
	        mapurl.put("50001", "http://res.haiziyouke.com");
	        mapurl.put("50002", "http://image.haiziyouke.com");
	        mapurl.put("50003", "http://video.haiziyouke.com");
	        mapurl.put("50004", "http://voice.haiziyouke.com");

	    }


//	public  static void main(String [] args)
//	{
//	    System.out.print("----"+getUserId());
//	}


	    public synchronized static long nextId() {
	        long timestamp = timeGen();
	        if (lastTimestamp == timestamp) {
	            sequence = (sequence + 1) & sequenceMask;
	            if (sequence == 0) {
	                logger.info("###########" + sequenceMask);
	                timestamp = tilNextMillis(lastTimestamp);
	            }

	        } else {
	            sequence = 0;
	        }

	        if (timestamp < lastTimestamp) {
	            try {
	                throw new Exception(
	                        String.format(
	                                "Clock moved backwards.  Refusing to generate id for %d milliseconds",
	                                lastTimestamp - timestamp));
	            } catch (Exception e) {
	               // e.printStackTrace();
	            	logger.error(e.getMessage());
	            }

	        }

	        lastTimestamp = timestamp;
	        long nextId = ((timestamp - twepoch << timestampLeftShift))
	                | (workerId << workerIdShift) | (sequence);
	        logger.info("timestamp:" + timestamp + ",timestampLeftShift:"
	                + timestampLeftShift + ",nextId:" + nextId + ",workerId:"
	                + workerId + ",sequence:" + sequence);
	        return nextId;
	    }



	    private static long tilNextMillis(final long lastTimestamp) {
	        long timestamp = timeGen();
	        while (timestamp <= lastTimestamp) {
	            timestamp = timeGen();
	        }
	        return timestamp;
	    }

	    private static long timeGen() {
	        return System.currentTimeMillis();
	    }
	    public static String getRandom(){
	        Random r=new Random();
	        String ve="";
	        for(int i=0;i<6;i++){
	            ve=ve+r.nextInt(10);
	        }
	        return ve;
	    }

	    /**
	     * 第三方登录生成的USERID
	     * @return
	     */
	    public static String generateNumber() {


	        return "2"+new Random().nextInt(9)+nextId();
	    }

	    /**
	 * 获取手机号的userid
	 * @param
	 * @return
	 */
	public static String getUserId()
	{

		String userId = "1"+new  Random().nextInt(9)+nextId();
		return userId;
	}

	    /**
	     * 将请求的字符做转码
	     * @param codename
	     * @return
	     */
	    public static String transcoding(String codename)
	    {
	        byte[] nameByte;
	        try {
	            nameByte = URLCodec.decodeUrl(codename.getBytes());
	            String name = new String(nameByte, "utf-8");
	            return name;
	        } catch (DecoderException e) {
	            //e.printStackTrace();
	        	logger.error(e.getMessage());
	        } catch (UnsupportedEncodingException e) {
	           // e.printStackTrace();
	        	logger.error(e.getMessage());
	        }
	        return codename;
	    }
	    /**
	     * 获取手机号码的accesstoken
	     * @param phone
	     * @return
	     */
	    public static String getAccessToken(String phone)
	    {
	        if(null == phone||"".equals(phone))
	        {
	            return null;
	        }
	        return phone.concat(String.valueOf(System.nanoTime()));

	    }

	    /**
	     * 获取七牛存储的bucket
	     * @param bucketCode
	     * @return
	     */
	    public static String getQiNiuBucket(String bucketCode)
	    {
	        if(null == bucketCode ||"".equals(bucketCode))
	        {
	            return null;
	        }
	        return map.get(bucketCode);
	    }

	    /**
	     * 获取七牛存储的地址
	     * @param bucketCode
	     * @return
	     */
	    public static String getQiNiuUrl(String bucketCode)
	    {
	        if(StringUtils.isBlank(bucketCode))
	        {
	            return null;
	        }
	        return mapurl.get(bucketCode);
	    }

	    public static String gettoken(String url){
	        String msg = "";// 保存调用http服务后的响应信息
	        try {
	            StringBuffer input= new StringBuffer();
	            URL u=new URL(url);
	            HttpURLConnection conn = (HttpURLConnection) u.openConnection();
	            conn.setRequestMethod("POST");
	            conn.setConnectTimeout(5 * 1000);
	            conn.setReadTimeout(20 * 1000);
	            // 使用 URL 连接进行输出，则将 DoOutput标志设置为 true
	            conn.setDoOutput(true);

	            byte[] data = input.toString().getBytes("UTF-8");
	            conn.setRequestProperty("Content-Type", "text/xml;charset=UTF-8");
	            conn.setRequestProperty("Content-Length", String.valueOf(data.length));
	            OutputStream outStream = conn.getOutputStream();// 返回写入到此连接的输出流
	            outStream.write(data);
	            outStream.close();
	            // 如果请求响应码是200，则表示成功
	            if (conn.getResponseCode() == 200) {
	                BufferedReader in = new BufferedReader(new InputStreamReader(
	                        (InputStream) conn.getInputStream(), "UTF-8"));
	                int by=0;
	                while((by=in.read())!=-1){
	                    msg = msg+in.readLine();
	                }
	                in.close();
	                conn.disconnect();// 断开连接
	            }
	        } catch (MalformedURLException e) {
	        	logger.error(e.getMessage());
	           // e.printStackTrace();
	        } catch (ProtocolException e) {
	        	logger.error(e.getMessage());
	        	//e.printStackTrace();
	        } catch (UnsupportedEncodingException e) {
	        	logger.error(e.getMessage());
	        	//e.printStackTrace();
	        } catch (IOException e) {
	        	logger.error(e.getMessage());
	        	// e.printStackTrace();
	        }
	        return msg;
	    }
	    
	    //加密手机号码
	    public static String getEncryPhone(String phone)
	    {
	    	if(StringUtils.isBlank(phone))
	    	{
	    		return null;
	    	}
	    	if(phone.length()!= 11)
	    	{
	    		return null;
	    	}
	    	return phone.substring(0, 3) + "****" + phone.substring(7, phone.length());
	    }

	/**
	 * 获取字符串的长度
	 * 汉字算一个字，字母2个字算一个字符
	 * @param str
	 * @return
	 */
	public static int getStringLength(String str)
		{
			int mylen = 0;
			if(StringUtils.isBlank(str)) {
				return mylen;
			}else {
				for(int i=0;i<str.length();i++){
					//如果字符串的第i个字符的Unicode码在0-128之间就是英文字符，应该算一个长度
					if(str.codePointAt(i)>0&&str.codePointAt(i)<128){
						mylen++;
					}else{
						//否则算两个长度
						mylen+=2;
					}
				}
				return mylen/2;
			}

		}

	/**
	 * 改进的32位FNV算法1
	 * @param data 字符串
	 * @return int值
	 */
	public static int FNVHash1(String data)
	{
		final int p = 16777619;
		int hash = (int)2166136261L;
		for(int i=0;i<data.length();i++)
			hash = (hash ^ data.charAt(i)) * p;
		hash += hash << 13;
		hash ^= hash >> 7;
		hash += hash << 3;
		hash ^= hash >> 17;
		hash += hash << 5;
		return hash;
	}

	public static long mixHash(String str)
	{
		long hash = str.hashCode();
		hash <<= 32;
		hash |= FNVHash1(str);
		return hash;
	}

	/**
	 * 清除掉所有特殊字符
	 * @author yifan
	 */

	public static String specialFit (String regex) {
		String regEx="[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]";
		Pattern p = Pattern.compile(regEx);
		Matcher m = p.matcher(regex);
		return m.replaceAll("").trim();
	}


}
